﻿using Aop.Api;
using Aop.Api.Request;
using Aop.Api.Response;
using Com.Alipay;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using WxPayAPI;

namespace WxPayJSAPI.Controllers
{
    public class AliPayController : Controller
    {
        // GET: AliPay
        public ActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public string sAlipay()
        {
            var 本地唯一标识号 = DateTime.Now.ToString("yyyyMMddHHmmss") + new Random().Next(100, 999);
            var backAli = AliPayConfigWap.AlipayWapPay("订单描述", 本地唯一标识号, Convert.ToDecimal(0.01));
            return backAli;
        }


        /// <summary>
        /// 支付成功后的 订单处理逻辑
        /// </summary>
        /// <param name="outTradeNo">订单号</param>
        /// <param name="httpContext">请求上下文</param>
        /// <param name="paymoney">余额应付金额</param>
        /// <returns>成功1</returns>
        public int PayHandle(string outTradeNo, HttpContextBase httpContext, DateTime? payTime = null, decimal paymoney = 0)
        {

            //根据订单号获取订单信息
            //var order = OrderService.GetOrderByOrderName(outTradeNo);
            //if (order == null)
            //{
            //    var lorder = OrderService.GetOrderList(new OrderRequest() { Trade_No = outTradeNo });
            //    order = lorder != null ? lorder.FirstOrDefault() : null;
            //    //  InsertUmeberLog("订单信息未找到" + outTradeNo, CommonCode.操作日志类型_订单操作, httpContext, outTradeNo);
            //    //订单信息未找到
            //    if (order == null)
            //    {
            //        return -3;
            //    }

            //}
            //if (paymoney == 0 && order.PayWay == CommonCode.支付类型_众享券)
            //{
            //    //InsertUmeberLog(outTradeNo + "订单金额异常", CommonCode.操作日志类型_订单操作, httpContext, outTradeNo);
            //    //订单金额异常
            //    return -2;
            //}
            //if (order.State == CommonCode.订单状态_待支付)
            //{
            //    var tmpStr = order.PayWay == CommonCode.支付类型_众享券 ? "余额" : "支付宝";
            //    //支付日志
            //    // InsertUmeberLog(outTradeNo + "订单开始" + tmpStr + "支付", CommonCode.操作日志类型_订单操作, httpContext, outTradeNo, order.OrderUserID);
            //    var momney = Convert.ToDecimal(order.Money);
            //    //支付结果
            //    var result = 1;

            //    string strDes = string.Empty;

            //    switch (order.PayWay)
            //    {
            //        case CommonCode.支付类型_众享券:
            //            //TODO 余额支付 处理逻辑
            //            order.PayWay = CommonCode.支付类型_众享券;
            //            strDes = "余额支付订单，流水号：" + outTradeNo + "  用户：" + StaticData.CurrentUser.Name + " 用户ID：" + StaticData.CurrentUser.ID + "  支付订单成功状态为《未发货》状态";

            //            break;

            //        case CommonCode.支付类型_支付宝:
            //            //TODO 支付宝支付成功 后续处理逻辑
            //            order.PayWay = CommonCode.支付类型_支付宝;
            //            strDes = "支付宝支付订单，流水号：" + outTradeNo + "  用户：" + StaticData.CurrentUser.Name + " 用户ID：" + StaticData.CurrentUser.ID + "  支付订单成功状态为《未发货》状态";
            //            break;
            //    }

            //    //TODO 支付成功
            //    order.State = CommonCode.订单状态_未发货;
            //    order.Trade_No = outTradeNo;
            //    order.PayTime = DateTime.Now;
            //    if (payTime != null)
            //    {
            //        order.PayTime = payTime;
            //    }
            //    OrderService.SaveOrder(order, strDes);
            //}
            //else
            //{
            //    //  InsertUmeberLog("当前订单状态【" + order.Base_CodeData_OrderState.CodeName + "】" + outTradeNo + "忽略支付请求", CommonCode.操作日志类型_订单操作, httpContext, outTradeNo, order.OrderUserID);
            //}
            return 1;
        }

        #region 订单支付
        /// <summary>
        /// 支付宝 同步支付  理论上无需修改
        /// </summary>
        public void ReturnHandle()
        {
            Log.Info("ReturnHandle", "【支付宝】调用了本地回调");
            var outTradeNo = Request.QueryString["out_trade_no"];
            //支付宝交易号
            string trade_no = Request.QueryString["trade_no"];
            //  common.InsertUmeberLog("支付宝同步支付请求" + outTradeNo, CommonCode.操作日志类型_订单操作, HttpContext, outTradeNo);
            Log.Info("ReturnHandle", "【支付宝】支付宝同步支付回调交易号：" + trade_no + " 本地订单号：" + outTradeNo);
            var sPara = GetRequestGet();


            Log.Info("ReturnHandle", "【支付宝】支付宝同步支付回调：" + sPara);

            Response.Write("【支付宝】支付宝同步支付回调交易号：" + trade_no + " 本地订单号：" + outTradeNo);
            return;
            if (sPara.Count > 0) //判断是否有带返回参数
            {
                var aliNotify = new Com.Alipay.Notify();

                bool verifyResult = Aop.Api.Util.AlipaySignature.RSACheckV1(sPara, AliPayConfigWap.alipay_public_key, AliPayConfigWap.input_charset, AliPayConfigWap.sign_type, false);
                if (verifyResult) //验证成功
                {
                    Log.Info("ReturnHandle", "【支付宝】支付宝同步支付回调=====支付成功");

                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                    //请在这里加上商户的业务逻辑程序代码
                    //——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
                    //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表

                    //商户订单号
                    //var outTradeNo = Request.QueryString["out_trade_no"];

                    //支付宝交易号
                    //string trade_no = Request.QueryString["trade_no"];

                    Response.Write("success:支付宝回调成功，等待Notify通知付款信息。请稍候"); //请不要修改或删除  
                    Response.Redirect("/Order/Index");
                    //交易状态
                    var tradeStatus = Request.QueryString["trade_status"];
                    if (tradeStatus == "TRADE_FINISHED" || tradeStatus == "TRADE_SUCCESS")
                    {
                        //判断该笔订单是否在商户网站中已经做过处理
                        //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                        //如果有做过处理，不执行商户的业务程序

                        PayHandle(outTradeNo, HttpContext);
                        //TODO 跳转页面
                        Response.Redirect("/Order/Index");
                        //  Response.Write("<script language=\"javascript\">window.opener=null; window.open('','_self');window.close();</script>");
                    }
                    else
                    {
                        //查询支付宝官方的交易状态
                        //获取签名
                        IAopClient client = new DefaultAopClient(AliPayConfigWap.alipayWang, AliPayConfigWap.app_id, AliPayConfigWap.private_key, "json", "1.0", "RSA2", AliPayConfigWap.alipay_public_key, AliPayConfigWap.input_charset, false);
                        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
                        request.BizContent = "{" +
                        "    \"out_trade_no\":\"" + outTradeNo + "\"," +
                        "    \"trade_no\":\"" + trade_no + "\"" +
                        "  }";
                        AlipayTradeQueryResponse response = client.Execute(request);
                        tradeStatus = response.TradeStatus;
                        //如果支付确认支付成功，则跳转到到订单模块
                        if (tradeStatus == "TRADE_FINISHED" || tradeStatus == "TRADE_SUCCESS")
                        {
                            //TODO 跳转页面
                            PayHandle(outTradeNo, HttpContext);
                            //TODO 跳转页面
                            Response.Redirect("/Order/Index");
                        }
                        else
                        {

                        }

                        // common.InsertUmeberLog("支付宝异步支付请求（" + tradeStatus + "）" + outTradeNo, CommonCode.操作日志类型_支付, HttpContext, outTradeNo);
                        //Response.Write("trade_status=" + tradeStatus);
                    }
                    //打印页面
                    // Response.Write("验证成功<br />");
                    //——请根据您的业务逻辑来编写程序（以上代码仅作参考）——
                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                }
                else //验证失败
                {
                    Log.Info("ReturnHandle", "【支付宝】支付宝同步支付回调=====支付失败");
                    //                    common.InsertUmeberLog(outTradeNo + "支付宝同步支付验证失败", CommonCode.操作日志类型_订单操作
                    //    , HttpContext, "notify_id：" + Request.QueryString["notify_id"] + "sign：" + Request.QueryString["sign"] + common.ToJson(sPara));
                    Response.Write("验证失败");
                }
            }
            else
            {
                Log.Info("NotifyHandle", "【支付宝】支付宝同步支付回调：无参数返回");
                //                common.InsertUmeberLog(outTradeNo + "支付宝同步支付无返回参数", CommonCode.操作日志类型_订单操作
                //, HttpContext, "notify_id：" + Request.QueryString["notify_id"] + "sign：" + Request.QueryString["sign"] + common.ToJson(sPara));
                Response.Write("无返回参数");
            }
        }
        /// <summary>
        /// 支付宝 异步支付  理论上无需修改
        /// </summary>
        public void NotifyHandle()
        {
            Log.Info("NotifyHandle", "【支付宝】调用了本地回调");
            var outTradeNo = Request.Form["out_trade_no"];
            //支付宝交易号
            string trade_no = Request.QueryString["trade_no"];
            //common.InsertUmeberLog("支付宝异步支付请求" + outTradeNo, CommonCode.操作日志类型_支付, HttpContext, outTradeNo);
            Log.Info("NotifyHandle", "【支付宝】支付宝异步支付回调交易号：" + trade_no + " 本地订单号：" + outTradeNo);

            Response.Write("【支付宝】支付宝异步支付回调交易号：" + trade_no + " 本地订单号：" + outTradeNo);
            return;

            var sPara = GetRequestPost();
            Log.Info("NotifyHandle", "【支付宝】支付宝异步支付回调：" + sPara);
            if (sPara.Count > 0) //判断是否有带返回参数
            {
                var aliNotify = new Com.Alipay.Notify();
                bool verifyResult = Aop.Api.Util.AlipaySignature.RSACheckV1(sPara, AliPayConfigWap.alipay_public_key, AliPayConfigWap.input_charset, AliPayConfigWap.sign_type, false);
                //var verifyResult = aliNotify.Verify(sPara, Request.Form["notify_id"], Request.Form["sign"]);
                if (verifyResult) //验证成功
                {
                    Log.Info("NotifyHandle", "【支付宝】支付宝异步支付回调：支付成功");
                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                    //请在这里加上商户的业务逻辑程序代码
                    //——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
                    //获取支付宝的通知返回参数，可参考技术文档中服务器异步通知参数列表

                    //商户订单号
                    //var outTradeNo = Request.Form["out_trade_no"];
                    //支付宝交易号
                    //var trade_no = Request.Form["trade_no"];
                    //交易状态
                    var tradeStatus = Request.Form["trade_status"];
                    if (tradeStatus == "TRADE_FINISHED" || tradeStatus == "TRADE_SUCCESS")
                    {
                        //判断该笔订单是否在商户网站中已经做过处理
                        //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                        //如果有做过处理，不执行商户的业务程序

                        //注意：
                        //该种交易状态只在两种情况下出现
                        //1、开通了普通即时到账，买家付款成功后。
                        //2、开通了高级即时到账，从该笔交易成功时间算起，过了签约时的可退款时限（如：三个月以内可退款、一年以内可退款等）后。

                        PayHandle(outTradeNo, HttpContext);

                        Response.Write("success"); //请不要修改或删除  

                        Response.Redirect("/Order/Index");
                    }
                    else
                    {
                        //common.InsertUmeberLog("支付宝异步支付请求（" + tradeStatus + "）" + outTradeNo, CommonCode.操作日志类型_支付, HttpContext, outTradeNo);
                    }
                    //——请根据您的业务逻辑来编写程序（以上代码仅作参考）——
                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                }
                else //验证失败
                {
                    Log.Info("NotifyHandle", "【支付宝】支付宝异步支付回调：支付失败");
                    //                    common.InsertUmeberLog(outTradeNo + "支付宝异步支付验证失败", CommonCode.操作日志类型_订单操作
                    //                        , HttpContext, "notify_id：" + Request.Form["notify_id"] + "sign：" + Request.Form["sign"] + common.ToJson(sPara));
                    Response.Write("fail");
                }
            }
            else
            {
                Log.Info("NotifyHandle", "【支付宝】支付宝异步支付回调：无参数返回");
                //                common.InsertUmeberLog(outTradeNo + "支付宝异步支付无返回参数", CommonCode.操作日志类型_订单操作
                //    , HttpContext, "notify_id：" + Request.Form["notify_id"] + "sign：" + Request.Form["sign"] + common.ToJson(sPara));
                Response.Write("无通知参数");
            }
        }


        /// <summary>
        /// 【返回】获取支付宝GET过来通知消息，并以“参数名=参数值”的形式组成数组
        /// </summary>
        /// <returns>request回来的信息组成的数组</returns>
        public SortedDictionary<string, string> GetRequestGet()
        {
            int i;
            var sArray = new SortedDictionary<string, string>();
            //Load Form variables into NameValueCollection variable.
            NameValueCollection coll = Request.QueryString;

            // Get names of all forms into a string array.
            String[] requestItem = coll.AllKeys;

            for (i = 0; i < requestItem.Length; i++)
            {
                sArray.Add(requestItem[i], Request.QueryString[requestItem[i]]);
            }

            return sArray;
        }


        /// <summary>
        /// 【异步】获取支付宝POST过来通知消息，并以“参数名=参数值”的形式组成数组
        /// </summary>
        /// <returns>request回来的信息组成的数组</returns>
        public SortedDictionary<string, string> GetRequestPost()
        {
            int i;
            var sArray = new SortedDictionary<string, string>();
            //Load Form variables into NameValueCollection variable.
            NameValueCollection coll = Request.Form;

            // Get names of all forms into a string array.
            String[] requestItem = coll.AllKeys;

            for (i = 0; i < requestItem.Length; i++)
            {
                sArray.Add(requestItem[i], Request.Form[requestItem[i]]);
            }

            return sArray;
        }

        #endregion


        #region 转账到个人支付宝账户

        public ActionResult alipayTransfer()
        {
            return View();
        }


        [HttpPost]
        public string transfer(string account,string name)
        {
            var 本地唯一标识号 = DateTime.Now.ToString("yyyyMMddHHmmss") + new Random().Next(100, 999);
            var  ali = AliPayConfigWap.AlipayTransfer(本地唯一标识号, account, "0.1", "支付宝转账测试", name, "测试转账");
            return ali;
        }

        #endregion
    }
}